#ifndef  _ELF_H_
#define  _ELF_H_


// 类型定义，宏定义。

// 基本数据类型：
// 我将 Elf 标准中的 unsigned char 改为 Elf64_Byte.

typedef  unsigned long long int  Elf64_Addr;
typedef  unsigned long long int  Elf64_Off;

typedef  unsigned char           Elf64_Byte;
typedef  unsigned short          Elf64_Half;

typedef  unsigned int            Elf64_Word;
typedef  signed int              Elf64_Sword;

typedef  unsigned long long int  Elf64_Xword;
typedef  signed long long int    Elf64_Sxword;

// 文件头结构。

#define EI_NIDENT       16

typedef  struct
{
    Elf64_Byte      e_ident[EI_NIDENT];
    Elf64_Half      e_type;
    Elf64_Half      e_version;
    Elf64_Word      e_machine;
    Elf64_Addr      e_entry;
    Elf64_Off       e_phoff;
    Elf64_Off       e_shoff;
    Elf64_Word      e_flags;
    Elf64_Half      e_ehsize;
    Elf64_Half      e_phentsize;
    Elf64_Half      e_phnum;
    Elf64_Half      e_shentsize;
    Elf64_Half      e_shnum;
    Elf64_Half      e_shstrndx;
} Elf64_Ehdr;

// 文件标志，e_ident
#define  EI_MAG0        0
#define  EI_MAG1        1
#define  EI_MAG2        2
#define  EI_MAG3        3
#define  EI_CLASS       4
#define  EI_DATA        5
#define  EI_VERSION     6
#define  EI_OSABI       7
#define  EI_ABIVERSION  8
#define  EI_PAD         9

// EI_CLASS
#define  ELFCLASSNONE   0
#define  ELFCLASS32     1
#define  ELFCLASS64     2


// EI_DATA
#define  ELFDATANONE    0
#define  ELFDATA2LSB    1
#define  ELFDATA2MSB    2


// 文件类型，e_type;
#define  ET_NONE        0
#define  ET_REL         1
#define  ET_EXEC        2
#define  ET_DYN         3
#define  ET_CORE        4


// CPU 类型，e_machine；
#define  EM_MMIX        80

// Elf 标准版本，e_version;
#define  EV_NONE        0
#define  EV_CURRENT     1

// 段头表中的入口结构。
typedef  struct
{
    Elf64_Word      sh_name;
    Elf64_Word      sh_type;
    Elf64_Xword     sh_flags;
    Elf64_Addr      sh_addr;
    Elf64_Off       sh_offset;
    Elf64_Xword     sh_size;
    Elf64_Word      sh_link;
    Elf64_Word      sh_info;
    Elf64_Xword     sh_addralign;
    Elf64_Xword     sh_entsize;
} Elf64_Shdr;

// 一些特殊的段索引值。
#define  SHN_UNDEF          0
#define  SHN_LORESERVE      0xff00
#define  SHN_LOPROC         0xff00
#define  SHN_HIPROC         0xff1f
#define  SHN_LOOS           0xff20
#define  SHN_HIOS           0xff3f
#define  SHN_ABS            0xfff1
#define  SHN_COMMON         0xfff2
#define  SHN_XINDEX         0xffff
#define  SHN_HIRESERVE      0xffff

// 段类型， sh_type
#define  SHT_NULL       0
#define  SHT_PROGBITS   1
#define  SHT_SYMTAB     2
#define  SHT_STRTAB     3
#define  SHT_RELA       4
#define  SHT_HASH       5
#define  SHT_DYNAMIC    6
#define  SHT_NOTE       7
#define  SHT_NOBITS     8
#define  SHT_REL        9
#define  SHT_SHLIB      10
#define  SHT_DYNSYM     11
#define  SHT_INIT_ARRAY 14
#define  SHT_FINI_ARRAY 15
#define  SHT_PREINIT_ARRAY  16
#define  SHT_GROUP      17
#define  SHT_SYMTAB_SHNDX   18


// 段标志位，sh_flags;
#define  SHF_WRITE      0x1
#define  SHF_ALLOC      0x2
#define  SHF_EXECINSTR  0x4
#define  SHF_MERGE      0x10
#define  SHF_STRINGS    0x20
#define  SHF_INFO_LINK  0x40
#define  SHF_LINK_ORDER 0x80
#define  SHF_OS_NONCONFORMING   0x100
#define  SHF_GROUP      0x200
#define  SHF_TLS        0x400


// 符号表，每个符号的结构；
typedef  struct
{
    Elf64_Word      st_name;
    Elf64_Byte      st_info;
    Elf64_Byte      st_other;
    Elf64_Half      st_shndx;
    Elf64_Addr      st_value;
    Elf64_Xword     st_size;
} Elf64_Sym;

// st_info 域的分解和合成。
#define  ELF64_ST_BIND(i)       ((i)>>4)
#define  ELF64_ST_TYPE(i)       ((i)&0xf)
#define  ELF64_ST_INFO(b,t)     (((b)<<4)+((t)&0xf))

// bind ..
#define  STB_LOCAL      0
#define  STB_GLOBAL     1
#define  STB_WEAK       2

// type
#define  STT_NOTYPE     0
#define  STT_OBJECT     1
#define  STT_FUNC       2
#define  STT_SECTION    3
#define  STT_FILE       4
#define  STT_COMMON     5
#define  STT_TLS        6


// st_other 中只含有 visibility 属性。
#define  ELF64_ST_VISIBILITY(o) ((o)&0x3)

// Visibility
#define  STV_DEFAULT    0
#define  STV_INTERNAL   1
#define  STV_HIDDEN     2
#define  STV_PROTECTED  3


// 重定位结构。
typedef  struct
{
    Elf64_Addr      r_offset;
    Elf64_Xword     r_info;
} Elf64_Rel;


typedef  struct 
{
    Elf64_Addr      r_offset;
    Elf64_Xword     r_info;
    Elf64_Sxword    r_addend;
} Elf64_Rela;

// r_info 域的合成和分解。
#define  ELF64_R_SYM(i)     ((i)>>32)
#define  ELF64_R_TYPE(i)    ((i)&0xffffffffL)
#define  ELF64_R_INFO(s,t)  (((s)<<32) + ((t)&0xffffffffL))


#if  0
// ELF 文件对象的操作。
// 创建，写，删除。
tetra  elf_create_file( tetra * sfname );
tetra  elf_write_file( tetra fid, tetra * fname );
void  elf_delete_file( tetra fid );


// 段管理。
tetra  elf_create_section( tetra fid, Elf64_Shdr * pshdr );

// 无结构的数据填加。
tetra  elf_add_data( tetra fid, tetra sid, tetra len, void * buf );


// 串表操作
tetra  elf_add_string( tetra fid, tetra * str );
tetra  elf_find_string( tetra fid, tetra * str );


// 符号表管理。
tetra  elf_add_symbol( tetra fid, Elf64_Sym * psym );
tetra  elf_read_symbol( tetra fid, Elf64_Sym * psym );
tetra  elf_write_symbol( tetra fid, tetra symid, Elf64_Sym * psym );


// 重定位管理。
tetra  elf_add_relocate( tetra fid, tetra sid, Elf64_Rel * prel );
tetra  elf_read_relocate( tetra fid, tetra sid, tetra rid, Elf64_Rel * prel );
tetra  elf_write_relocate( tetra fid, tetra sid, tetra rid, Elf64_Rel * prel );
#endif

#endif

